package kr.ac.kaist.savehearts.ui;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;

import kr.ac.kaist.savehearts.Configure;
import kr.ac.kaist.savehearts.SaveHeartsConstants;
import kr.ac.kaist.savehearts.auth.UserInfo;
import kr.ac.kaist.savehearts.location.LocationTrackingListener;
import kr.ac.kaist.savehearts.location.UserLocationTracker;
import kr.ac.kaist.savehearts.status.MapOverlays;
import kr.ac.kaist.savehearts.status.StatusUpdateListener;
import kr.ac.kaist.savehearts.status.UserStatusUpdater;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.TabHost;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class MainActivity extends MapActivity 
	implements OnClickListener, TabHost.OnTabChangeListener, 
		LocationTrackingListener, OnKeyListener, StatusUpdateListener {
	
	private static final String TAG = MainActivity.class.getSimpleName();
	
	private TabHost tabHostMain = null;
	
	private MapView mapViewMain;
	
	private Button buttonSettingsAccount;
	private Button buttonSettingsGPS;
	private Button buttonAppShare;
	private Button buttonHelp;
	private Button buttonLogout;
	private Button buttonAbout;
	private Button buttonMainList;
	private Button buttonMainEmergency;
	
	private List<Overlay> mapOverlays;
	private Drawable drawableUser;
	private MapOverlays itemizedOverlays; 
	private UserLocationTracker locationTracker;
	private UserStatusUpdater statusUpdater;
	
	/**
	 * getPoint() returns a GeoPoint object which points the location
	 * @param lat Latitude of a point
	 * @param lon Longitude of a point
	 * @return A GeoPoint object which points the location
	 */
	private GeoPoint getPoint(double lat, double lon) {
    	return(new GeoPoint((int)(lat*1000000.0), (int)(lon*1000000.0)));
    }
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		buttonSettingsAccount = (Button)findViewById(R.id.buttonSettingsAccount);
		buttonSettingsAccount.setOnClickListener(this);
		buttonSettingsGPS = (Button)findViewById(R.id.buttonSettingsGPS);
		buttonSettingsGPS.setOnClickListener(this);
		buttonAppShare = (Button)findViewById(R.id.buttonAppShare);
		buttonAppShare.setOnClickListener(this);
		buttonHelp = (Button)findViewById(R.id.buttonHelp);
		buttonHelp.setOnClickListener(this);
		buttonLogout = (Button)findViewById(R.id.buttonLogout);
		buttonLogout.setOnClickListener(this);
		buttonAbout = (Button)findViewById(R.id.buttonAbout);
		buttonAbout.setOnClickListener(this);
		buttonMainList = (Button)findViewById(R.id.buttonMainList);
		buttonMainList.setOnClickListener(this);
		buttonMainEmergency = (Button)findViewById(R.id.buttonMainEmergency);
		buttonMainEmergency.setOnClickListener(this);
		
		loadConfiguration();
		
		tabHostMain = (TabHost)findViewById(R.id.tabhostMain);
		tabHostMain.setup();
		tabHostMain.addTab(tabHostMain.newTabSpec(SaveHeartsConstants.TAB_RESCUE).setIndicator(getString(R.string.rescue)).setContent(R.id.tabMap));
		tabHostMain.addTab(tabHostMain.newTabSpec(SaveHeartsConstants.TAB_AED).setIndicator(getString(R.string.aed)).setContent(R.id.tabMap));
		tabHostMain.addTab(tabHostMain.newTabSpec(SaveHeartsConstants.TAB_SETTINGS).setIndicator(getString(R.string.settings)).setContent(R.id.tabSettings));
		
		tabHostMain.setCurrentTab(1);
		tabHostMain.setCurrentTab(0);
		tabHostMain.setOnTabChangedListener(this);
		tabHostMain.refreshDrawableState();
		
		locationTracker = UserLocationTracker.getInstance(this);
		locationTracker.setListener(this);
//		locationTracker.setUpdateInterval(Configure.getInstance().getGPSInterval() *
//					SaveHeartsConstants.MIN_IN_MS);
		locationTracker.setUpdateInterval(0);
		locationTracker.startTracking();
		
		statusUpdater = UserStatusUpdater.getInstance();
		
		mapViewMain = (MapView)findViewById(R.id.mapViewMain);
		
		mapViewMain.setBuiltInZoomControls(true);
		mapViewMain.displayZoomControls(true);

		if (mapViewMain != null) {
			MapController myMapController = mapViewMain.getController();
			mapViewMain.setSatellite(false);

			mapOverlays = mapViewMain.getOverlays();
			drawableUser = this.getResources().getDrawable(R.drawable.me);
			itemizedOverlays = new MapOverlays(drawableUser, this);
			
			myMapController.setZoom(SaveHeartsConstants.DEFAULT_ZOOM_LEVEL);
			myMapController.setCenter(getPoint(SaveHeartsConstants.DEFAULT_LATITUDE,
					SaveHeartsConstants.DEFAULT_LONGITUDE));
		}
	}
	
	private void loadConfiguration() {
		Configure configure = Configure.getInstance();
		configure.setGPSInterval(SaveHeartsConstants.DEFAULT_GPS_INTERVAL_MIN);
	}
	
	private void clearOverlays() {
		if ( mapOverlays != null ) mapOverlays.clear();
		if ( mapViewMain != null ) mapViewMain.refreshDrawableState();
		if ( itemizedOverlays != null ) itemizedOverlays.clearOverlays();
	}
	
	private void addOverlays(double latitude, double longitude, String name, String desc) {
		if ( mapOverlays == null ) return;
		GeoPoint point = getPoint(latitude, longitude);
		OverlayItem item = new OverlayItem(point, name, desc);
		itemizedOverlays.addOverlay(item);
		mapOverlays.add(itemizedOverlays);
	}

	@Override
	public void onClick(View v) {
		Intent myIntent;
		switch ( v.getId() ) {
			case R.id.buttonSettingsAccount:
				
				break;
			case R.id.buttonSettingsGPS:
				myIntent = new Intent(MainActivity.this, GPSSettingsActivity.class);
				startActivity(myIntent);
				break;
			case R.id.buttonAppShare:
				
				break;
			case R.id.buttonHelp:
				myIntent = new Intent(MainActivity.this, HelpActivity.class);
				startActivity(myIntent);
				break;
			case R.id.buttonAbout:
				
				break;
			case R.id.buttonLogout:
				
				break;
			case R.id.buttonMainList:
				myIntent = new Intent(MainActivity.this, AEDInfoActivity.class);
				startActivity(myIntent);
				break;
			case R.id.buttonMainEmergency:
				
				break;
			default:
				break;
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public void onTabChanged(String tabId) {
		Log.d(TAG, "onTabChanged(" + tabId + ")");
	}

	@Override
	public void locationUpdated(Location location) {
		if ( mapViewMain == null ) return;
		
		if ( Configure.getInstance().getUserInfo() != null ) {
			Configure.getInstance().getUserInfo().setLatitude(location.getLatitude());
			Configure.getInstance().getUserInfo().setLongitude(location.getLongitude());
		}
		mapViewMain.getController().animateTo(getPoint(location.getLatitude(), location.getLongitude()));
	}

	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event) {
		if ( keyCode == KeyEvent.KEYCODE_BACK ) {
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle(getString(R.string.app_name));
			builder.setMessage(getString(R.string.quit))
					.setCancelable(false)
					.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// if the user clicks [YES], exit the application.
							System.exit(0);
						}
					})
					.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// do nothing...							
						}
					});
			AlertDialog dialog = builder.create();
			dialog.show();
		}
		return false;
	}

	/**
	 * neighborUpdated() is called when received the list of nearby users from the server.
	 * The application frequently sends a report current location and receives neighbors' information.
	 * For more information, please refer to
	 * 		kr.ac.kaist.savehearts.MpaStatusUpdater
	 */
	@Override
	public void neighborUpdated(ArrayList<UserInfo> neighbors) {
		// clear overlays
		clearOverlays();
		// add overlays to the mapview to show neighbors on the map
		for ( UserInfo user : neighbors ) {
			addOverlays(user.getLatitude(), user.getLongitude(), user.getId(), user.getFullName());
		}
	}

	@Override
	public void responseReceived(RequestType reqType, int response) {
		// TODO Auto-generated method stub
		
	}

}
